# coding:utf-8
"""
description:kyla 整体可公用的元素操作
"""
import os
import random
import time

from common import Base_Page, Log
from appium.webdriver.common import mobileby

from common.Gesture_Mainpulation import gesture_mainpulation
from common.Get_Yaml import get_yaml
from common.Log import LOG
from config.GlobalParameter import TEST_Element_YAML

testData = get_yaml(os.path.join(TEST_Element_YAML, 'Public.yaml'))


class public_elements(Base_Page.Base_page):
    By = mobileby.MobileBy()

    def func_ButtonCancel(self):
        """
        1.logout取消
        :return:
        """
        self.click_button()
        self.click_cancel()

    def func_ButtonConfirm(self):
        """
        1.logout成功
        :return:
        """
        self.click_button()
        self.click_confirm()

    def func_backCancel(self):
        """
        点击返回取消
        :return:
        """
        self.click_btnBack()
        self.click_cancel()

    def func_backConfirm(self):
        """
        确认返回
        :return:
        """
        self.click_btnBack()
        self.click_confirm()

    """点击cancel"""
    cancel_loc = (By.ID, testData.get_elementInfo(0))
    """点击confirm"""
    confirm_loc = (By.ID, testData.get_elementInfo(1))
    """点击back"""
    btnBack_loc = (By.ID, testData.get_elementInfo(2))
    """点击修改name弹框关闭按钮"""
    btnClosePopup_loc = (By.ID, testData.get_elementInfo(3))

    """name输入框
    1.Scene name"""
    NameInputPopup_loc = (By.ID, testData.get_elementInfo(4))
    """点击name弹框的save按钮"""
    InputPopupSave_loc = (By.ID, testData.get_elementInfo(5))

    """点击button
    1.logout注销按钮"""
    button_loc = (By.CLASS_NAME, testData.get_elementInfo(6))

    def click_cancel(self):
        """点击cancel"""
        self.find_element(*self.cancel_loc).click()

    def click_confirm(self):
        """点击confirm"""
        if self.assertVisible(*self.confirm_loc):
            self.find_element(*self.confirm_loc).click()

    def assertVisible_confirm(self):
        """ 1.判断confirm按钮是否存在"""
        return self.assertVisible(*self.confirm_loc)

    def assertVisibleAndClick_confirm(self):
        """ 1.判断confirm按钮是否存在,存在就点击确认按钮"""
        if self.assertVisible_confirm():
            self.click_confirm()

    def assertVisible_back(self):
        """判断btnBack按钮是否存在"""
        return self.assertVisible(*self.btnBack_loc)

    def click_btnBack(self, LoopN=1):
        """点击back"""
        for i in range(LoopN):
            self.find_element(*self.btnBack_loc).click()

    def click_ClosePopup(self):
        """点击修改name弹框关闭按钮"""
        self.find_element(*self.btnClosePopup_loc).click()

    def input_EditName(self, name):
        """name输入框"""
        self.send_keys(name, self.find_element(*self.NameInputPopup_loc))

    def click_InputPopupSave(self):
        """点击name弹框的save按钮"""
        self.find_element(*self.InputPopupSave_loc).click()

    def func_input_name(self, Name):
        """
        输入name名称,1.Scene name
        2.home management name
        :param Name:
        :param message:
        :return:
        """
        self.input_EditName(Name)
        self.click_InputPopupSave()

    def func_CheckNameError(self, Name, check):
        """
        Name输入框验证为空、超过十个中文、验证超过20个英文异常测试
        :return:返回bool集合
        """
        BList = []
        for index, row in enumerate(Name):
            self.input_EditName(row)
            self.click_InputPopupSave()
            BList.append(super().find_toast(check[index]))
        return BList

    def click_button(self):
        """点击button"""
        self.find_element(*self.button_loc).click()

    def assertVisible_btn(self):
        """ 1.判断btnlogout按钮是否存在
        2.判断Warning pop -up的ok按钮是否存在"""
        return self.assertVisible(*self.button_loc)

    """NumberPicker弹框,
       1.滑动选择When all conditions are met或When one of the condition is met选项。
       2.Add tasks devices，sort by
       3.PM2.5 sensor两个选择框，选择<、>=，和Good、fair、poor and very poor
       4.Motion sensor选择Hold time。5.station Brightness
       other:timer
    """
    popup_NumberPicker_input_loc = (By.ID, testData.get_elementInfo(7))
    """NumberPicker弹框的confirm按钮"""
    popup_NumberPicker_confirm_loc = (By.ID, testData.get_elementInfo(8))
    """点击NumberPicker弹框的cancel按钮"""
    popup_NumberPicker_cancel_loc = (By.ID, testData.get_elementInfo(9))

    """condition的schedule，和 device mode选择时间弹框confirm按钮"""
    popup_timepicker_confirm_loc = (By.ID, testData.get_elementInfo(10))
    """condition的schedule，和 device mode选择时间弹框cancel按钮"""
    popup_timepicker_cancel_loc = (By.ID, testData.get_elementInfo(11))

    def get_NumberPicker_input(self):
        """
        获取number picker的滑动项文字
        :return: 返回NumberPicker input的内容
        """
        return self.find_element(*self.popup_NumberPicker_input_loc).text

    def get_NumberPicker(self):
        """
        获取number picker 元素
        :return:
        """
        return self.find_elements(*self.popup_NumberPicker_input_loc)

    def click_popup_NumberPicker_confirm(self):
        """NumberPicker弹框的confirm按钮"""
        self.find_element(*self.popup_NumberPicker_confirm_loc).click()

    def click_popup_NumberPicker_cancel(self):
        """点击NumberPicker弹框的cancel按钮"""
        self.find_element(*self.popup_NumberPicker_cancel_loc).click()

    def click_popup_timepicker_confirm(self):
        """condition的schedule，和 device mode选择时间弹框confirm按钮"""
        self.find_element(*self.popup_timepicker_confirm_loc).click()

    def click_popup_timepicker_cancel(self):
        """condition的schedule，和 device mode选择时间弹框cancel按钮"""
        self.find_element(*self.popup_timepicker_cancel_loc).click()

    def swipe_NumberPicker_input(self, indexs=0, upAndDown="up", times=1):
        """
        滑动number picker
        :param indexs: number picker索引号，用于时间分钟秒滑动
        :param upAndDown: up上滑，down下滑
        :param times: 滑动次数
        :return:
        """
        try:
            centre = gesture_mainpulation().centreXAndY(self.get_NumberPicker()[indexs])
            if upAndDown == "up":
                for i in range(times):
                    """向上滑，固定滑动一个,滑动次数"""
                    self.driver.swipe(centre[0], centre[3], centre[0], centre[5] - 60, 200)  # 上滑，y大到小
            else:
                for i in range(times):
                    """向下滑，固定滑动一个,滑动次数"""
                    self.driver.swipe(centre[0], centre[5], centre[0], centre[3] + 60, 200)  # 下滑，y小到大
        except:
            LOG.error("滑动失败，检查被测设备的坐标是否能正常操作。。。")

    def swipe_NumberPicker_Text(self, texts, indexs=0):
        """
        循环滑动时间，滑到当前hour，和滑到当前时间下一分钟
        :param texts:  当前时间hour或者minute
        :param indexs:  NumberPicker索引号
        :return:
        """
        centre = gesture_mainpulation().centreXAndY(self.get_NumberPicker()[indexs])
        try:
            for i in range(100):
                """向上滑，固定滑动一个,滑动次数"""
                self.driver.swipe(centre[0], centre[3], centre[0], centre[5] - 30)  # 上滑，y大到小
                print(int(self.get_NumberPicker()[indexs].text),int(texts))
                if int(self.get_NumberPicker()[indexs].text) == int(texts):
                    break
        except:
            LOG.error("滑动失败，检查被测设备的坐标是否能正常操作。。。")

    def func_NumberPickerCancel(self, times):
        """
        1.滑动选择When all conditions are met或When one of the condition is met选项。
        2.Add tasks devices，sort by
        3.关于选择delay time的元素
                other:
        1.condition的schedule，和 device mode选择时间弹框cancel按钮
        :return:
        """
        self.swipe_NumberPicker_input(0, "down", times)

        if self.assertVisible(*self.popup_NumberPicker_cancel_loc):
            LOG.info("判断number picker弹框选择的cancel存在")
            self.click_popup_NumberPicker_cancel()
        # elif self.assertVisible(*self.popup_timepicker_cancel_loc):
        else:
            LOG.info("判断time picker弹框选择的cancel存在")
            self.click_popup_timepicker_cancel()

    def func_NumberPickerComfirm(self, indexs=0, upAndDown="up", times=1):
        """
        1.滑动选择When all conditions are met或When one of the condition is met选项。
        2.Add tasks devices，sort by
        3.关于选择delay time的元素
        other:
        1.condition的schedule，和 device mode选择时间弹框confirm按钮
        :return:
        """
        self.swipe_NumberPicker_input(indexs, upAndDown, times)
        if self.assertVisible(*self.popup_NumberPicker_confirm_loc):
            LOG.info("判断number picker弹框选择的confirm存在")
            self.click_popup_NumberPicker_confirm()
        # elif self.assertVisible(*self.popup_timepicker_confirm_loc):
        else:
            LOG.info("判断time picker弹框选择的confirm存在")
            self.click_popup_timepicker_confirm()

    """点击列表项最右侧的back图标，跳转页面或弹框。返回集合"""
    ImageBack_loc = (By.XPATH, testData.get_elementInfo(12))

    def get_ImageBack(self):
        """点击列表项最右侧的back图标，跳转页面或弹框。返回集合"""
        return self.find_elements(*self.ImageBack_loc)

    """点击删除弹框的delete按钮"""
    btnDeletePopupDelete_loc = (By.ID, testData.get_elementInfo(13))
    """点击删除弹框的cancel按钮"""
    btnDeletePopupCancel_loc = (By.ID, testData.get_elementInfo(14))

    def click_btnDeletePopupDelete(self):
        """点击删除弹框的delete按钮"""
        self.find_element(*self.btnDeletePopupDelete_loc).click()

    def click_btnDeletePopupCancel(self):
        """点击删除弹框的cancel按钮"""
        self.find_element(*self.btnDeletePopupCancel_loc).click()

    def func_RandomXOrCancel(self):
        """ 随机点击左上角“X” icon（close pop ）还是cancel按钮关闭弹框 """
        if random.randint(1, 2) == 1:
            self.click_btnDeletePopupCancel()
        else:
            self.click_ClosePopup()  # 左上角“X”icon

    """home management》QR home》pop-up、station add IR 》3-step guide pop-up的later按钮"""
    btnLater_loc = (By.ID, testData.get_elementInfo(15))

    def click_btnLater(self):
        """home management》QR home》pop-up、
        station add IR 》3-step guide pop-up的later按钮"""
        self.find_element(*self.btnLater_loc).click()

    """滑动有列表项的弹框pop-up.security、Add room 、Add Floor、Add device>Select Room、Location"""
    designSheet_loc = (By.ID, testData.get_elementInfo(16))

    def swipe_designSheet(self, LoopN=1):
        """滑动有列表项的弹框pop-up.security、Add room 、Add Floor、Add device>Select Room、Location"""
        for i in range(LoopN):
            gesture_mainpulation().swipe_up(self.driver, self.find_element(*self.designSheet_loc))

    """点击弹框右上角的next按钮"""
    PopupNext_loc = (By.ID, testData.get_elementInfo(17))

    def click_PopupNext(self):
        """点击弹框右上角的next按钮"""
        self.find_element(*self.PopupNext_loc).click()

    """select room弹框，点击或获取room name"""
    availableRoomName_loc = (By.ID, testData.get_elementInfo(18))

    def get_availableRoomName(self):
        """select room弹框，点击或获取room name"""
        return self.find_elements(*self.availableRoomName_loc)

    """select room弹框，点击或获取Floor name"""
    availableRoomFloor_loc = (By.ID, testData.get_elementInfo(19))

    def get_availableRoomFloor(self):
        """select room弹框，点击或获取Floor name"""
        return self.find_elements(*self.availableRoomFloor_loc)

    """Device Setting，修改Device name------------------------------------------------------------"""
    SettingsName_loc = (By.ID, testData.get_elementInfo(20))

    def click_SettingsName(self):
        """Device Setting，修改Device name。弹框elements见第3，4，5。function见func_CheckName"""
        self.find_element(*self.SettingsName_loc).click()

    def get_SettingsName(self):
        """Device Setting，获取Device name。"""
        return self.find_element(*self.SettingsName_loc).text

    def edit_SettingsName(self, DevName):
        """
        function,修改Device Name
        :param DevName:输入框内容Device Name，并且作为断言
        """
        self.func_input_name(DevName)
        return super().find_toast(DevName)

    # Device Setting，修改Location
    SettingsLocation_loc = (By.ID, testData.get_elementInfo(21))

    def click_SettingsLocation(self):
        """Device Setting，修改Location"""
        self.find_element(*self.SettingsLocation_loc).click()

    def edit_SettingsLocation(self, RoomName, Message):
        """
        function,设置location
        :param RoomName:根据RoomName点击，并断言内容
        :param Message:
        :return:
        """
        for i in range(20):  # 滑动弹框
            for index, row in enumerate(self.get_availableRoomName()):
                print("设置location--{}---{}".format(RoomName, row.text))
                if RoomName in row.text:
                    row.click()
                    return super().find_toast(Message)  # 直接跳出整个方法
            self.swipe_designSheet()

    # Device Setting，Connected Device(s)》hub和smart station可用
    ConnectedDevices_loc = (By.ID, testData.get_elementInfo(22))

    def get_ConnectedDevices(self):
        """Device Setting，Connected Device(s)》hub和smart station可用"""
        return self.find_element(*self.ConnectedDevices_loc)

    #     info: 23,Device Setting，点击Hub、Station、plug、high power、
    #     ceiling light、Curtain and Roller Blind的 Check for Update一行
    SettingsUpdate_loc = (By.ID, testData.get_elementInfo(23))

    def click_SettingsUpdate(self):
        """info: 23,Device Setting，点击Hub、Station、plug、high power、
        ceiling light、Curtain and Roller Blind的 Check for Update一行
        略过，没有固件版本更新
        """
        self.find_element(*self.SettingsUpdate_loc).click()

    def get_SettingsUpdate(self):
        """info: 23,Device Setting，点击Hub、Station、plug、high power、
        ceiling light、Curtain and Roller Blind的 Check for Update一行显示为‘updated’，则不更新
        """
        return self.find_element(*self.SettingsUpdate_loc).text

    def func_ForUpdate(self):
        """更新Device Fireware version"""
        AgoText = self.get_SettingsVersion()
        print(self.get_SettingsUpdate())
        if self.get_SettingsUpdate() == "Updated":
            return True
        else:
            self.click_SettingsUpdate()
            self.click_confirm()
            time.sleep(60)  # 预留时间来更新
            LOG.info("等待1min来更新version，更新前v：{}，更新后v：{} >>>".format(AgoText, self.get_SettingsVersion()))
            return AgoText != self.get_SettingsVersion()

    # Device Setting，获取device connection状态，Online and Offline
    SettingsOnline_loc = (By.ID, testData.get_elementInfo(24))

    def get_SettingsStatus(self):
        """Device Setting，获取device connection状态，Online and Offline"""
        return self.find_element(*self.SettingsOnline_loc).text

    #     info: 23,Device Setting，点击Hub、Station、plug、high power、
    #     ceiling light、Curtain and Roller Blind的 Reconfigure Device一行
    SettingsReconfigure_loc = (By.ID, testData.get_elementInfo(25))

    def click_SettingsReconfigure(self):
        """info: 23,Device Setting，点击Hub、Station、plug、high power、
        ceiling light、Curtain and Roller Blind的 Reconfigure Device一行
        """
        # 上滑后出现Reconfigure 一行才能点击
        gesture_mainpulation().swipe_up(self.driver, self.get_DeviceSettingsPage())
        self.find_element(*self.SettingsReconfigure_loc).click()

    # Device Setting>Reconfigure Device,输入WiFi名称
    PopupReConfigSsid_loc = (By.ID, testData.get_elementInfo(33))

    def input_PopupReConfigSsid(self, PopupReConfigSsid):
        """Device Setting>Reconfigure Device,输入WiFi名称"""
        self.send_keys(PopupReConfigSsid, self.find_element(*self.PopupReConfigSsid_loc))

    # Device Setting>Reconfigure Device,输入WiFi 密码。为空时弹框按钮elements见第0，1
    PopupReConfigPw_loc = (By.ID, testData.get_elementInfo(34))

    def input_PopupReConfigPw(self, PopupReConfigPw):
        """Device Setting>Reconfigure Device,输入WiFi 密码。为空时弹框按钮elements见第0，1"""
        self.send_keys(PopupReConfigPw, self.find_element(*self.PopupReConfigPw_loc))

    def func_PopupSsidPwd(self, PopupReConfigSsid, PopupReConfigPw):
        """
        验证Ssid或者pwd输入框为空时
        :param PopupReConfigSsid: Ssid或者pwd输入框内容
        :param PopupReConfigPw:
        """
        self.input_PopupReConfigSsid(PopupReConfigSsid)
        self.input_PopupReConfigPw(PopupReConfigPw)
        self.click_btnPopupReConfigOk()

    # Device Setting>Reconfigure Device,点击弹框的ok按钮
    btnPopupReConfigOk_loc = (By.ID, testData.get_elementInfo(35))

    def click_btnPopupReConfigOk(self):
        """Device Setting>Reconfigure Device,点击弹框的ok按钮"""
        self.find_element(*self.btnPopupReConfigOk_loc).click()

    def func_Reconfigure(self, PopupReConfigSsid, PopupReConfigPw, BackNum, Messages):
        """
        正常输入Wifi ssid和pwd，会出现1.wifi和之前一样。则获取弹框内容，并关闭弹框
        2.修改成功。断言setting page的online是否会出现
        3.设备离线，点击ok后跳转页面。再点击手机返回键，断言Reconfigure 是否存在
        :param PopupReConfigSsid:wifi名称
        :param PopupReConfigPw:wifi密码
        :param Messages:断言弹框内容
        :param BackNum:从add device page返回到setting page的返回次数
        """
        self.click_ClosePopup()  # 关闭验证ssid和pwd输入框的弹框
        self.click_SettingsReconfigure()  # 重新点击Reconfigure Device一行
        self.input_PopupReConfigSsid(PopupReConfigSsid)
        self.input_PopupReConfigPw(PopupReConfigPw)
        self.click_btnPopupReConfigOk()
        # 如果Reconfigure Device 一行存在，则表示Reconfigure设备为online
        if self.find_toast(Messages[0]):
            LOG.info("Reconfigure Device三种情况>>>1.wifi和之前一样。则获取弹框内容，并关闭弹框...")
            self.click_ClosePopup()
            return True
        elif self.find_toast(Messages[1]):
            LOG.info("Reconfigure Device三种情况>>>3.设备离线，点击ok后跳转页面。再点击手机返回键，断言Reconfigure Device一行要存在...")
            for i in range(BackNum):
                self.driver.keyevent(4)  # 点击手机返回键
            self.click_ClosePopup()
            return self.assertVisible(*self.SettingsReconfigure_loc)
        else:
            LOG.info("Reconfigure Device三种情况>>>2.修改成功。断言setting page的online是否会出现...")
            return self.find_toast("Online")  # 等待设备为Online

    # Device Setting，点击REMOVE DEVICE按钮
    SettingsRemove_loc = (By.ID, testData.get_elementInfo(26))

    def click_SettingsRemove(self):
        """Device Setting，点击REMOVE DEVICE按钮"""
        self.find_element(*self.SettingsRemove_loc).click()

    def func_SettingRemove(self, Message):
        """
        点击Device settings页面的底部remove按钮
        :return:
        """
        gesture_mainpulation().swipe_up(self.driver, self.get_DeviceSettingsPage())
        self.click_SettingsRemove()
        if random.randint(1, 2) == 1:
            self.click_cancel()
            re = self.assertVisible(*self.SettingsRemove_loc)  # cancel就是关闭弹框，还停留在该页
            self.click_btnBack(2)  # 循环点击两次back，固定setting page》control page》dashboard page
        else:
            self.click_confirm()
            re = self.find_toast(Message)  # 断言提示
        return re

    # Device Setting，there sensor，button，switches和dimmer设备获取Connected hub
    ConnectedHub_loc = (By.ID, testData.get_elementInfo(27))

    def Func_ConnectedHub(self):
        gesture_mainpulation().swipe_up(self.driver, self.get_DeviceSettingsPage())  # 滑动Setting page
        """Device Setting，there sensor，button，switches和dimmer设备获取Connected hub"""
        LOG.info("{}连接的hub是：{}>>>".format(self.get_SettingsName(), self.find_element(*self.ConnectedHub_loc).text))

    # Device Setting，修改plug、high power、switches、dimmer的Connected Appliance
    SettingsAppliance_loc = (By.ID, testData.get_elementInfo(28))

    def get_SettingsAppliance(self):
        """Device Setting，点击plug、high power、switches、dimmer的Connected Appliance一行"""
        return self.find_element(*self.SettingsAppliance_loc)

    # Device Setting>Appliance icon Name,选择并获取文字
    ApplianceName_loc = (By.ID, testData.get_elementInfo(32))

    def get_ApplianceName(self):
        """Device Setting>Appliance icon Name,选择并获取文字"""
        return self.find_elements(*self.ApplianceName_loc)

    def func_ApplianceIcon(self):
        """
        修改Appliance icon Name，随机选择Appliance name
        """
        self.get_SettingsAppliance().click()  # 点击Appliance一行
        self.swipe_designSheet()
        num = random.randint(0, len(self.get_ApplianceName()) - 1)  # 获取显示框内数据长度作为随机数
        print(len(self.get_ApplianceName()) - 1, num)
        AgoText = self.get_ApplianceName()[num].text  # 根据随机数作为索引，获取文字
        self.get_ApplianceName()[num].click()  # 根据随机数作为索引点击
        if self.assertVisible_btn():
            self.click_button()  # 点击warning框的确认按钮
        self.find_toast("successfully")  # 先找到提示框后在断言Appliance 文字
        print(AgoText, self.get_SettingsAppliance().text)
        return AgoText == self.get_SettingsAppliance().text

    # Device Setting，点击Curtain and Roller Blind》Reverse Motor一行
    ReverseMotor_loc = (By.ID, testData.get_elementInfo(29))

    def click_ReverseMotor(self):
        """Device Setting，点击Curtain and Roller Blind》Reverse Motor一行"""
        self.find_element(*self.ReverseMotor_loc).click()

    def func_ReverseMotor(self):
        """随机Appliance icon Name"""
        gesture_mainpulation().swipe_up(self.driver, self.get_DeviceSettingsPage())  # 滑动Setting page
        self.click_ReverseMotor()
        self.click_cancel()
        return self.assertVisible(*self.ReverseMotor_loc)  # 关闭弹框后还停留再该页

    # Device Setting，点击Curtain and Roller Blind》Recalibrate一行
    Recalibrate_loc = (By.ID, testData.get_elementInfo(30))

    def click_Recalibrate(self):
        """Device Setting，点击Curtain and Roller Blind》Recalibrate一行"""
        self.find_element(*self.Recalibrate_loc).click()

    def func_Recalibrate(self, message):
        """随机Appliance icon Name"""
        self.click_Recalibrate()
        self.click_confirm()
        return super().find_toast(message)

    # Device Setting，滑动Device Setting page
    svDeviceSettings_loc = (By.ID, testData.get_elementInfo(31))

    def get_DeviceSettingsPage(self):
        """
        Device Setting，滑动Device Setting page。
        可进行上下滑动，此方法不固定
        """
        return self.find_element(*self.svDeviceSettings_loc)

    # Device Setting>获取Firmware version
    SettingsVersion_loc = (By.ID, testData.get_elementInfo(36))

    def get_SettingsVersion(self):
        """Device Setting>获取Firmware version"""
        return self.find_element(*self.SettingsVersion_loc)

    # Device Control page>点击右上角第一个？icon
    DeviceControlTip_loc = (By.ID, testData.get_elementInfo(37))

    def click_DeviceControlTip(self):
        """Device Control page>点击右上角第一个？icon"""
        self.find_element(*self.DeviceControlTip_loc).click()

    # Device Control page>点击右上角第二个设置图标
    ControlSettings_loc = (By.ID, testData.get_elementInfo(38))

    def click_ControlSettings(self):
        """Device Control page>点击右上角第二个设置图标"""
        if self.assertVisible(*self.ControlSettings_loc):
            self.find_element(*self.ControlSettings_loc).click()
        else:
            LOG.info("进入control page功能说明页/或进入station connected devices页，点击手机返回...")
            self.driver.keyevent(4)  # 点击手机返回键
            self.find_element(*self.ControlSettings_loc).click()
